package com.base.cn.platform.os.common.utils.ke96;


import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.utils.CcLiveUtils;
import com.base.cn.platform.os.common.utils.FileExportImportUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.http.HttpUtil;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.manage.config.SysConfig;
import com.base.cn.platform.os.service.manage.config.SysConfigService;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import static com.base.cn.platform.os.common.utils.BaseUtil.gson;


/**
 * @author ZJH
 * @描述 96ke执行方法
 * @Date 2019/7/27
 */
@Component
@Slf4j
public class Ke96ServiceUtils {

    @Autowired
    private SysConfigService sysConfigService;

    /**
     *创建小班课直播间
     * @param parameter
     * @return
     * @throws IOException
     */
    public Map<String, Object> createCcSmallLiveData(Map parameter) throws IOException {

        String url = "https://ccapi.csslcloud.net/api/room/create";
        Map<String, Object> resultMaps = demandSmall(url,parameter);

        if(resultMaps.get("result").equals("OK")){
            HashMap<String,String> mapTo = new HashMap<>();
            Map roomMap = (Map) resultMaps.get("data");
            mapTo.put("room_id",roomMap.get("roomid").toString());
            mapTo.put("sign",roomMap.get("roomid").toString());
            return ResultUtil.SUCCESS("直播间数据创建成功",mapTo);
        }
        return ResultUtil.ERROR("创建失败",resultMaps.get("reason"));
    }

    /**
     *获取小班课房间信息
     * @param room_id
     * @return
     * @throws IOException
     */
    public Map<String, Object> getCcSmallLiveInfoData(String room_id) throws IOException {
        String url = "https://ccapi.csslcloud.net/api/room/room_detail";
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("roomid",room_id);
        Map<String, Object> resultMaps = demandSmall(url,paramsMap);
        if(resultMaps.get("result").equals("OK")){
            Map roomMap = (Map) resultMaps.get("data");
            return ResultUtil.SUCCESS("直播间数据创建成功",roomMap);
        }
        return ResultUtil.ERROR("获取直播间信息失败",resultMaps.get("reason"));
    }

    /**
     * 获取直播访问记录
     * @param roomId
     * @return
     */
    public List<Map<String,Object>> liveVisitData(String roomId) throws IOException {
        List<Map<String,Object>> userLiveRecordList = new ArrayList<>();
        //根据直播间id获取所有的直播
        Map<String,Object> params = new HashMap<>();
        params.put("roomid",roomId);
        String url = "http://api.csslcloud.net/api/v2/live/info";
        Map<String, Object> resultMap = demandLive(url,params);
        if(resultMap.get("result").equals("OK")){
            List<Map<String,Object>> liveList = (List<Map<String, Object>>) resultMap.get("lives");
            for(Map<String,Object> live : liveList){
                List<Map<String,Object>> list = userLiveRecordData(live.get("id").toString());
                userLiveRecordList.addAll(list);
            }
        }
        return userLiveRecordList;
    }

    public List<Map<String,Object>> userLiveRecordData(String liveId) throws IOException {
        List<Map<String,Object>> userLiveRecordList = new ArrayList<>();
        Map<String,Object> params = new HashMap<>();
        params.put("liveid",liveId);
        params.put("pagenum","1000");
        String _url = "http://api.csslcloud.net/api/statis/live/useraction";
        Map<String, Object> resultMaps  = demandLive(_url,params);
        if(resultMaps.get("result").equals("OK")){
            userLiveRecordList = (List<Map<String, Object>>) resultMaps.get("userEnterLeaveActions");
        }
        return userLiveRecordList;
    }


    /**
     * 获取小班课直播访问记录
     * @param roomId
     * @return
     */
    public List<Map<String,Object>> smallLiveVisitData(String roomId, String openTime, String endTime) throws IOException {
        List<Map<String,Object>> userLiveRecordList = new ArrayList<>();
        //根据直播间id获取所有的直播
        Map<String,Object> params = new HashMap<>();
        params.put("roomid",roomId);
        params.put("start_time",openTime);
        params.put("end_time",endTime);
        String url = "https://ccapi.csslcloud.net/collect/live/record";
        Map<String, Object> resultMap = demandSmall(url,params);
        if(resultMap.get("result").equals("OK")){
            List<Map<String,Object>> liveList = (List<Map<String, Object>>) resultMap.get("data");
            for(Map<String,Object> live : liveList){
                List<Map<String,Object>> list = smallLiveRecordData(roomId,live.get("liveid").toString());
                userLiveRecordList.addAll(list);
            }
        }
        return userLiveRecordList;
    }

    public List<Map<String,Object>> smallLiveRecordData(String roomId, String liveId) throws IOException {
        List<Map<String,Object>> userLiveRecordList = new ArrayList<>();
        Map<String,Object> params = new HashMap<>();
        params.put("roomid",roomId);
        params.put("liveid",liveId);
        String _url = "https://ccapi.csslcloud.net/collect/live/user/record/";
        Map<String, Object> resultMaps  = demandLive(_url,params);
        if(resultMaps.get("result").equals("OK")){
            userLiveRecordList = (List<Map<String, Object>>) resultMaps.get("data");
        }
        return userLiveRecordList;
    }

    /**
     * 处理直播数据
     * @param userLiveRecordList 列表数据
     * @return
     */
    public List<List<String>> getLiveData(List<Map<String,Object>> userLiveRecordList){
        List<List<String>> data = new ArrayList<>();
        userLiveRecordList.forEach((v)->{
            String terminal = "";
            if(v.get("terminal").toString().equals("0")){
                terminal = "PC端";
            }else{
                terminal = "移动端";
            }

            data.add(Arrays.asList(
                    v.get("viewerId").toString(),
                    v.get("viewerName").toString(),
                    v.get("viewerIp").toString(),
                    v.get("watchTime").toString(),
                    v.get("enterTime").toString(),
                    v.get("leaveTime").toString(),
                    terminal
            ));
        });
        return  data;
    }

    /**
     *
     * @param data 表格数据
     * @param heads 表格头部
     * @param expName 表格名称
     * @param srcFile 文件列表容器
     * @throws Exception
     */
    public static void generateFile(List<List<String>> data,String [] heads,String expName,List<Map<String,Object>> srcFile) throws Exception {
        Map<String,Object> files = new HashMap<>();
        InputStream inputStream = FileExportImportUtil.createExcel(heads, data);
        files.put("name",expName);
        files.put("inputStream",inputStream);
        srcFile.add(files);
    }

    /**
     * 处理小班课数据
     * @param userLiveRecordList 列表数据
     * @return
     */
    public List<List<String>> getSmallLiveData(List<Map<String,Object>> userLiveRecordList){
        List<List<String>> data = new ArrayList<>();
        userLiveRecordList.forEach((v)->{
            String terminal = "";
            if(v.get("platform").toString().equals("Web")){
                terminal = "PC端";
            }else{
                terminal = "移动端";
            }

            data.add(Arrays.asList(
                    v.get("viewerid").toString(),
                    v.get("username").toString(),
                    v.get("ip").toString(),
                    v.get("duration").toString(),
                    v.get("enter_time").toString(),
                    v.get("exit_time").toString(),
                    terminal
            ));
        });
        return  data;
    }

    /**
     * 小班课公共请求接口
     * @param url
     * @param params
     * @return
     * @throws IOException
     */
    public Map<String, Object> demandSmall(String url,Map params) throws IOException {
        //获取96直播配置
        TreeMap<String,String> configMap = sysConfigService.getSysConfigContext(ConfigName.VLASPROVIDER);
        params.put("userid",configMap.get("ccAppId"));
        Long timestamp = System.currentTimeMillis()/1000;
        String hash = CcLiveUtils.createHashedQueryString(params,timestamp,configMap.get("liveAppKey"));
        String result = HttpUtil.doGet(url+"?" + hash);
        return gson.fromJson(result, new TypeToken<Map<String, Object>>() {}.getType());
    }


    /**
     * 96k直播公共请求地址
     * @param url
     * @param params
     * @return
     * @throws IOException
     */
    public Map<String, Object> demandLive(String url,Map params) throws IOException {
        //获取96直播配置
        TreeMap<String,String> configMap = sysConfigService.getSysConfigContext(ConfigName.VLASPROVIDER);
        params.put("userid",configMap.get("ccAppId"));
        Long timestamp = System.currentTimeMillis()/1000;
        String hash = CcLiveUtils.createHashedQueryString(params,timestamp,configMap.get("liveAppKey"));
        String result = HttpUtil.doGet(url+"?" + hash);
        return gson.fromJson(result, new TypeToken<Map<String, Object>>() {}.getType());
    }

    public Long  findLiveUserView(String liveId) {
        Map<String, Object> params = new HashMap<>();
        params.put("liveid", liveId);
        Map<String,Object> resultMap=null;
        try {
            resultMap = demand("http://api.csslcloud.net/api/statis/userview", params);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        if ("OK".equals(resultMap.get("result"))) {
            long totalCount = new Double(resultMap.get("totalCount").toString()).longValue();
            return totalCount;
        }
        return null;
    }

    public Long findLiveUserMsg(String roomId, String liveId) {
        Map<String, Object> params = new HashMap<>();
        params.put("liveid", liveId);
        params.put("roomid", roomId);
        params.put("userid", this.getLiveId());
        Map<String,Object> resultMap=null;
        try {
            resultMap = demand("http://api.csslcloud.net/api/live/chatmsg", params);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        if ("OK".equals(resultMap.get("result"))) {
            long count = new Double(resultMap.get("count").toString()).longValue();
            return count;
        }
        return null;
    }

    /**
     * 获取直播互动记录
     *
     * @return
     */
    public Map<String, Object> getLiveInteractiveList(String liveId,String pageNum,String  pageIndex) {
        Map<String, Object> params = new HashMap<>();
        params.put("liveid", liveId);
        params.put("pagenum",pageNum);
        params.put("pageindex", pageIndex);
        Map<String, Object> result = new HashMap<>();
        try {
            result = this.demand("http://api.csslcloud.net/api/statis/interactive", params);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if ("OK".equals(result.get("result"))) {
            return result;
        }
        return  null;
    }

    /**
     * 获取聊天信息记录
     * @return
     */
    public Map<String, Object> getChatMsg(String liveId,String pageNum,String pageIndex,String roomId) {
        Map<String, Object> params = new HashMap<>();
        params.put("roomid", roomId);
        params.put("liveid", liveId);
        params.put("pagenum",pageNum);
        params.put("pageindex", pageIndex);
        Map<String, Object> result = new HashMap<>();
        try {
            result = this.demand("http://api.csslcloud.net/api/live/chatmsg", params);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if ("OK".equals(result.get("result"))) {
            return result;
        }
        return  null;
    }

    /**
     * 获取签到记录id
     * @return
     */
    public String  getRollcall(String liveId,String roomId) {
        Map<String, Object> params = new HashMap<>();
        params.put("roomid", roomId);
        params.put("liveid", liveId);
        Map<String, Object> result = new HashMap<>();
        try {
            result = this.demand("http://api.csslcloud.net/api/live/rollcall", params);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if ("OK".equals(result.get("result"))) {
            List<Map<String,Object>> rollcallList = (List<Map<String, Object>>) result.get("rollcalls");
            if (ObjectUtils.isNotEmpty(rollcallList)) {
                return rollcallList.get(0).get("rollcallId").toString();
            }
        }
        return  null;
    }


    public Map<String, Object> getUseRollCallList(String liveId,String roomId,String pageNum,String pageIndex) {
        Map<String, Object> params = new HashMap<>();
        params.put("roomid", roomId);
        params.put("liveid", liveId);
        params.put("pagenum",pageNum);
        params.put("pageindex", pageIndex);
        params.put("rollcallid", getRollcall(liveId, roomId));

        Map<String, Object> result = new HashMap<>();
        try {
            result = this.demand("http://api.csslcloud.net/api/v2/live/rollcall/viewers", params);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if ("OK".equals(result.get("result"))) {
            return result;
        }
        return  null;
    }

    /**
     * 调用CC直播接口
     *
     * @param url
     * @param params
     * @return
     * @throws IOException
     */
    public Map<String, Object> demand(String url, Map params) throws IOException {
        if (StringUtils.isEmpty(getLiveId())) {
            HashMap<String, Object> res = new HashMap<>();
            res.put("result", "NO");
            res.put("reason", "未开通直播账户");
            return res;
        }
        params.put("userid", getLiveId());
        String apiKey = getLiveApiKey();
        if (StringUtils.isEmpty(apiKey)) {
            HashMap<String, Object> resulMap = new HashMap<>();
            resulMap.put("reason", "秘钥丢失");
            return ResultUtil.ERROR("调用失败", resulMap);
        }
        String hash = CcLiveUtils.createHashedQueryString(params, apiKey);
        String result = HttpUtil.doGet(url + "?" + hash);
        return gson.fromJson(result, new TypeToken<Map<String, Object>>() {
        }.getType());
    }
    /**
     * 获取直播apikey
     *
     * @return
     * @throws IOException
     */
    public String getLiveApiKey() throws IOException {
        TreeMap<String, String> keData = getUser96keData();

        if (ObjectUtils.isNotEmpty(keData.get("liveapikey"))) {
            return keData.get("liveapikey");
        }
        Map<String, Object> liveAccInfo1 = getLiveAccInfo();
        if (ObjectUtils.isNotEmpty(liveAccInfo1) && ObjectUtils.isNotEmpty(liveAccInfo1.get("liveapikey"))) {
            //设置key不需要重新
            SysConfig sysConfigByConfigType = sysConfigService.getSysConfigByConfigType(ConfigName.V96K);
            TreeMap<String, String> contextTreeMap = sysConfigByConfigType.getContextTreeMap();
            contextTreeMap.put("liveapikey", liveAccInfo1.get("liveapikey").toString());
            sysConfigByConfigType.setContext(gson.toJson(contextTreeMap));
            sysConfigService.saveConfig(sysConfigByConfigType);
            return liveAccInfo1.get("liveapikey").toString();
        }
        return "";
    }
    /**
     * 获取直播账号
     *
     * @return
     */
    public String getLiveId() {
        return getUser96keData().get("userId");
    }
    /**
     * 获取用户96ke数据
     *
     * @return
     */
    public TreeMap<String, String> getUser96keData() {

        return sysConfigService.getSysConfigContext(ConfigName.V96K);

    }

    /**
     * 获取直播账号信息
     *
     * @return
     */
    public Map<String, Object> getLiveAccInfo() throws IOException {
        Map map = new HashMap<>();
        map.put("userid", getLiveId());
        Map<String, Object> live = live(getLiveAccInfoApi(), map);

        if (ObjectUtils.isEmpty(live.get("error"))) {
            return (Map<String, Object>) live.get("userinfo");
        } else {
            log.error(live.toString());
        }

        return null;
    }

    /**
     * 获取修改点播空间
     */
    public String getLiveAccInfoApi() {
        return get96KeData().get("liveAccInfo");
    }

    /**
     * 获取配置信息
     *
     * @return
     */
    public TreeMap<String, String> get96KeData() {
        TreeMap<String, String> sysConfigContext = sysConfigService.getSysConfigContext(ConfigName.V96K);
        log.error("======================" + sysConfigContext.toString());
        return sysConfigContext;
    }

    public Map<String, Object> live(String url, Map params) throws IOException {
        params.put("organizer", getOrganizer());
        String hash = CcLiveUtils.createHashedQueryString(params, getLiveKey());
        String result = HttpUtil.doGet(url + "?" + hash);

        return gson.fromJson(result, new TypeToken<Map<String, Object>>() {
        }.getType());
    }

    /**
     * 获取直播密钥
     *
     * @return
     */
    public String getLiveKey() {
        return get96KeData().get("organizerKey");
    }

    /**
     * 获取集团账号
     *
     * @return
     */
    public String getOrganizer() {
        return get96KeData().get("organizer");

    }

    /**
     * 获取所有直播间的所有用户
     *
     * @param roomId    直播间ID 必填
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param pageNum   页码
     * @param pageIndex 页面索引
     * @return
     */
    public List<Map> getLiveList(String roomId, String startTime, String endTime, String pageNum, String pageIndex) {
        Map<String, Object> params = new HashMap<>();
        params.put("roomid", roomId);
        if (ObjectUtils.isNotEmpty(pageNum)) {
            params.put("pagenum", pageNum);
        }
        if (ObjectUtils.isNotEmpty(pageIndex)) {
            params.put("pageindex", pageIndex);
        }
        if (ObjectUtils.isNotEmpty(startTime)) {
            params.put("starttime", startTime);
        }
        if (ObjectUtils.isNotEmpty(endTime)) {
            params.put("endtime", endTime);
        }
        Map<String, Object> resultMaps = null;
        try {
            resultMaps = demand("http://api.csslcloud.net/api/v2/live/info", params);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        if (ObjectUtils.isNotEmpty(resultMaps.get("result")) && resultMaps.get("result").equals("OK")) {
            return (List<Map>) resultMaps.get("lives");
        }
        return null;
    }

}